package com.borya.util.filter;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.borya.framework.core.ServerRequest;
import com.borya.framework.core.ServerResponse;
import com.borya.framework.util.ObjectUtils;
import com.borya.model.db.User;
import com.borya.model.entity.HeaderEntity;
import com.borya.model.entity.UserToken;
import com.borya.statuscode.StatusCode;
import com.borya.util.Constant;
import com.borya.util.HTTPUtils;

import io.netty.handler.codec.http.HttpHeaders;
import io.netty.util.CharsetUtil;

/**
 * @author 陈彪
 * @blame 陈彪
 * @date 2020/3/25 15:54
 */
public class FilterUtil {

	private static final Logger log = Logger.getLogger(FilterUtil.class);

	private static String filterUrl = Constant.SDK_APP_AUTH_URL + "/auth/c/auth/check";

	/**
	 * 单点结算sdk的鉴权
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	public static boolean filterSdkApp(ServerRequest request, ServerResponse response) {
		final String url = request.uri();
		final String boryaAuth = request.headers().get("boryaAuth");
		Map<String, String> header = new HashMap<>(4);
		String host = getIp(request);
		boolean uploadImgFile = false;
		if (url.contains("c/uploadImgFile")) {
			uploadImgFile = true;
		}
		String authorization;
		Optional<String> body;
		if (uploadImgFile) {
			// 文件流上传，曾经请求体里的body放到了hearder的authrizatuon中
			authorization = request.headers().get("Authorization");
			body = Optional.empty();
		} else {
			// 请求体
			authorization = "";
			body = Optional.of(request.text());
		}

		Map<String, String> headers = new HashMap<String, String>();
		headers.put("boryaAuth", boryaAuth);
		headers.put("url", url);
		headers.put("host", host);
		headers.put("Authorization", authorization);

		Optional<String> result = HTTPUtils.sendPost(filterUrl, body, headers);

		if (!result.isPresent()) {
			// 鉴权服务器请求失败
			log.warn(String.format("鉴权失败,\nheader:{%s},\nsend:{%s},\nresult:{%s}", header, body, result));
			response.content().writeBytes(StatusCode.SYSTEM_BUSY.json().toString().getBytes(CharsetUtil.UTF_8));
			return true;
		}
		JSONObject res = JSONObject.parseObject(result.get());
		if (Objects.isNull(res) || !Objects.equals(StatusCode.SUCCESS.num(), res.getString("code"))) {
			// 鉴权失败
			log.warn(String.format("鉴权失败,\nheader:{%s},\nsend:{%s},\nresult:{%s}", header, body, result));
			response.content().writeBytes(result.get().getBytes(CharsetUtil.UTF_8));
			return true;
		}
		JSONObject data = res.getJSONObject("data");
		if (Objects.isNull(data)) {
			// 返回用户不存在
			log.warn(String.format("鉴权网元返回data不存在,\nheader:{%s},\nsend:{%s},\nresult:{%s}", header, body, result));
			response.content().writeBytes(StatusCode.SYSTEM_EXCEPTION.toJSON().getBytes(CharsetUtil.UTF_8));
			return true;
		}
		UserToken userToken = data.getObject("userToken", UserToken.class);
		request.setAttribute("userToken", userToken);
		User user = data.getObject("user", User.class);
		if (Objects.isNull(user)) {
			// 返回用户不存在
			log.warn(String.format("鉴权网元返回user不存在,\nheader:{%s},\nsend:{%s},\nresult:{%s}", header, body, result));
			response.content().writeBytes(StatusCode.SYSTEM_EXCEPTION.toJSON().getBytes(CharsetUtil.UTF_8));
			return true;
		}
		request.setAttribute("user", user);
		JSONObject json = data.getJSONObject("body");
		log.info(String.format("url:{%s},\nget:{%s}", url, json));
		request.setAttribute("json", json);
		HeaderEntity authHeader = JSON.parseObject(data.getString("boryaAuth"), HeaderEntity.class);
		request.setAttribute("boryaAuth", authHeader);
		return false;
	}

	private static String getIp(ServerRequest request) {
		HttpHeaders headers = request.headers();
		String ip = headers.get("http_x_forwarded_for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = headers.get("x-forwarded-for");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = headers.get("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = headers.get("WL-Proxy-Client-IP");
		}
		ip = ObjectUtils.isNullOrEmpty(ip) ? request.ip() : ip;
		if (ip.contains(",")) {
			ip = ip.split(",")[0].trim();
		}
		return ObjectUtils.isNullOrEmpty(ip) ? request.ip() : ip;
	}
}
